package cz.via.wowss.dao;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.TypedQuery;

import cz.via.wowss.controller.MainController;
import cz.via.wowss.entities.Company;
import cz.via.wowss.entities.Player;
import cz.via.wowss.entities.PlayerTransaction;
import cz.via.wowss.entities.Shareholder;

public class TransactionDao implements ITransactionDao {

	public synchronized boolean buyShare(Company c, int count, int playerId) {

		EntityManager em = MainController.emf.createEntityManager();

		EntityTransaction t = em.getTransaction();

		try {
			t.begin();

			if (c.getStockLeft() < count)
				throw new Exception();

			c.setStockLeft(c.getStockLeft() - count);

			TypedQuery<Shareholder> q = em
					.createQuery(
							"SELECT s FROM Shareholder s WHERE s.player=:playerId AND s.company=:companyId",
							Shareholder.class);
			q.setParameter("playerId", em.find(Player.class, playerId));
			q.setParameter("companyId", c);
			List<Shareholder> l = q.getResultList();

			Shareholder s;

			IGameDao gameDao = new GameDao();

			Player p = gameDao.getPlayerById(playerId);

			BigDecimal price = c.getValue().multiply(new BigDecimal(count));

			if (p.getMoney().compareTo(price) < 0)
				throw new Exception();

			double portionBought = (double) count / (double) c.getStock();			
			c.setValue(c.getValue().add(new BigDecimal(3 * portionBought)));
			
			if (!l.isEmpty()) {
				s = l.get(0);
				s.setStockCount(s.getStockCount() + count);
			} else {
				s = new Shareholder();
				s.setCompany(c);
				s.setPlayer(p);
				s.setStockCount(count);
			}

			p.setMoney(p.getMoney().subtract(price));
			

			em.merge(c);
			em.merge(p);
			em.merge(s);

			t.commit();

		} catch (Exception e) {
			t.rollback();
			e.printStackTrace();
			return false;
		} finally {
			em.close();
		}

		return true;
	}

	public synchronized boolean sellShare(Company c, int count, int playerId) {

		EntityManager em = MainController.emf.createEntityManager();

		EntityTransaction t = em.getTransaction();

		try {
			t.begin();

			TypedQuery<Shareholder> q = em
					.createQuery(
							"SELECT s FROM Shareholder s WHERE s.player=:playerId AND s.company=:companyId",
							Shareholder.class);
			q.setParameter("playerId", em.find(Player.class, playerId));
			q.setParameter("companyId", c);
			List<Shareholder> l = q.getResultList();

			if (l.isEmpty())
				return false;
			Shareholder s = l.get(0);
			if (s.getStockCount() < count)
				return false;

			IGameDao gameDao = new GameDao();

			Player p = gameDao.getPlayerById(playerId);

			
			
			p.setMoney(p.getMoney().add(
					c.getValue().multiply(new BigDecimal(count))));
			c.setStockLeft(c.getStockLeft() + count);

			double portionSold = (double) count / (double) c.getStock();	
			
			BigDecimal d = c.getValue().subtract(new BigDecimal(3 * (portionSold)));
			
			if(d.compareTo(new BigDecimal(0.5)) < 0) {
				d = new BigDecimal(0.5);
			}
			
			c.setValue(d);
			
			if (s.getStockCount() == count) {
				// Smazat shareholder

				em.remove(s);
				System.out.println("del");
			} else {
				// Nechat share holder
				s.setStockCount(s.getStockCount() - count);
				em.merge(s);
			}

			em.merge(p);
			em.merge(c);

			t.commit();
		} catch (Exception e) {
			t.rollback();
			e.printStackTrace();
			return false;
		} finally {
			em.close();
		}
		return true;
	}

	// Zatim se nepouziva
	public List<PlayerTransaction> getTransactions(int playerId, Date from,
			Date to) {
		// TODO Auto-generated method stub
		return null;
	}

}
